package com.gzmu.myprint.handler;

import com.gzmu.myprint.mapper.CostMapper;
import com.gzmu.myprint.mapper.PrintUserMapper;
import com.gzmu.myprint.model.Cost;
import com.gzmu.myprint.model.PrintUser;
import com.gzmu.myprint.model.User;
import com.gzmu.myprint.vo.JacksonUtil;
import com.gzmu.myprint.vo.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * SocketHandler
 *
 * @author XiongNeng
 * @version 1.0
 * @since 2018/3/22
 */
@Component
public class SocketHandler extends TextWebSocketHandler {
    @Autowired
    public PrintUserMapper userMapper;
    @Autowired
    public CostMapper costMapper;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static final Map<String, WebSocketSession> sessions;

    static {
        sessions = new HashMap <>();
    }

    private static final Map<String, String> webusers;
    static {
        webusers =  new HashMap<>();
    }

    public SocketHandler() {
    }

    //List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
    //private SimpMessageSendingOperations simpMessageSendingOperations;

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message){
        String msg = message.getPayload();
        String [] fields = msg.split(":");
        logger.info("+++msg:" + msg);
        if (fields.length >= 5){
            Message job = JacksonUtil.json2Bean(msg, new TypeReference<Message>(){});
            if (job.getType().equals("request")){
                webusers.put(job.getFrom(),session.getId());
            }else if(job.getType().equals("messsage")){
                String from = job.getFrom();
                String to = job.getTo();
                String id = webusers.get(to);
                if (id != null) {
                    //logger.info("+++Content:" + job.getContent());
                    sendMessageToUserById(id, new TextMessage(job.getContent()));
                }
                int index = from.indexOf("print");
                if (index > -1){
                    double price;
                    int uid = Integer.valueOf(to);
                    String content = job.getContent();
                    String [] contents = content.split(":");
                    if (contents[7].equals("1") || !contents[9].equals("0")){
                        if (contents[1].equals("1")){
                            if (contents[11].equals(1))
                                price = Integer.valueOf(contents[5]) * 0.6;
                            else
                                price = Integer.valueOf(contents[5]) * 0.4;
                        }else{
                            price = Integer.valueOf(contents[5]) * 0.3;
                        }
                        Cost cost = new Cost();
                        cost.setUid(uid);
                        cost.setName(contents[13]);
                        cost.setPrice(price);
                        cost.setType(Integer.valueOf(contents[1]));
                        cost.setTime(df.format(new Date()));
                        costMapper.InsertCost(cost);
                        PrintUser user = userMapper.findUserByUid(uid);
                        double oldMoney = user.getMoney() - price;
                        System.out.println(" money:" + oldMoney);
                        userMapper.upDateUserOfPrice(uid, oldMoney);
                    }
                }
                //TextMessage tm  = new TextMessage("server return");
                //sendMessageToUser(session, tm);
            }//heartbeat
        }
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.put(session.getId(), session);
        logger.info("+++new user content id:" + session.getId() + "  user size:" + sessions.size());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String id = session.getId();
        for (Map.Entry<String, String> entry : webusers.entrySet()) {
            if (entry.getValue().equals(id)){
                webusers.remove(entry.getKey());
            }
        }
        sessions.remove(id);
        session.close();
        logger.info("+++user discontent id:" + session.getId() + "  user size:" + sessions.size());
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable throwable) throws Exception {
        logger.error("error occured at sender " + session, throwable);
    }

    /**
     * 给所有的用户发送消息
     */
    public void sendMessagesToUsers(TextMessage message) {
        for (String userId : sessions.keySet()) {
            try {
                if (sessions.get(userId).isOpen()) {
                    sessions.get(userId).sendMessage(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 发送消息给指定的用户
     */
    private void sendMessageToUser(WebSocketSession session, TextMessage message) {
        try {
            // 在线就发送
            if (session.isOpen()) {
                session.sendMessage(message);
            }
        } catch (IOException e) {
           logger.error("发送消息给指定的用户出错", e);
        }
    }
    /**
     * 发送消息给指定的用户
     */
    public void sendMessageToUserById(String userId, TextMessage message) {
        //logger.info("userId " + userId);
        WebSocketSession session = sessions.get(userId);
        sendMessageToUser(session, message);
    }
}
